package com.jishuo.nontax.bfc.service;

import com.github.pagehelper.PageHelper;
import com.jishuo.base.bean.BaseResult;
import com.jishuo.base.bean.ErrorCodeEnum;
import com.jishuo.base.bean.Pagination;
import com.jishuo.base.config.NonTaxConfig;
import com.jishuo.base.dao.UserMapper;
import com.jishuo.base.service.SequenceService;
import com.jishuo.base.util.ExportSXSSFUtil;
import com.jishuo.base.util.MD5;
import com.jishuo.nontax.bean.bank.Bank;
import com.jishuo.nontax.bean.bank.OnlineOrder;
import com.jishuo.nontax.bean.bank.PunishLatefee;
import com.jishuo.nontax.bean.message.*;
import com.jishuo.nontax.bean.vo.IllegalactivityinfoVO;
import com.jishuo.nontax.bean.vo.PunishDetailInfoVO;
import com.jishuo.nontax.bean.vo.PunishInfoVO;
import com.jishuo.nontax.bfc.dao.*;
import com.jishuo.nontax.bfc.pzk.PzkService;
import com.jishuo.nontax.bfc.tlq.MessageFactory;
import com.jishuo.nontax.bfc.tlq.MessageService;

import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Service;

import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author :hanlipeng
 * @description :
 * @create :2022-12-22 13:46:00
 */
@Service
public class PunishService {

    private static Logger logger = LoggerFactory.getLogger(DivideService.class);
    @Resource
    private PunishMapper punishMapper;
    @Resource
    private MessageService messageService;
    @Resource
    private SequenceService sequenceService;
    @Resource
    private IllegalactivityinfoMapper illegalactivityinfoMapper;
    @Resource
    NonTaxConfig nonTaxConfig;

    @Resource
    private UserMapper userMapper;
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public BaseResult sendPayInfo(String billnum) {

        try {
            long messageid = sequenceService.getNextSeq("ELEMESSAGESEQ");

            IllegalactivityinfoVO illegalactivityinfoVO = illegalactivityinfoMapper.selectInfo(billnum);


            Object o = MessageFactory.setPayInfo(illegalactivityinfoVO);
            //发送到财政
            messageService.sendMessage("SETPAYINFO", messageid, o, "2.0");
            // 写凭证
            if (nonTaxConfig.IS_Pzk) {
                PzkService.sendPzk("SETPAYINFOPZK", o);
            }
            return new BaseResult();
        } catch (Exception e) {
            logger.info("失败：" + e.toString());
            return new BaseResult(ErrorCodeEnum.UNKNOWN_ERR);
        }
    }

    public void setLatefee(String data, int billstate, String sn) {

        if (billstate == 1) {
            try {
                //xml解析器
                Serializer serializer = new Persister();
                //返回交罚对象
                SetLategee setLategee = serializer.read(SetLategee.class, new StringReader(data));

                PunishInfoVO punishInfoVO = new PunishInfoVO(setLategee);

                if (punishMapper.findPunishCount(punishInfoVO) > 0) {
                    punishMapper.updatePunishState(punishInfoVO);

                } else {
                    punishInfoVO.setPunishinfoid(sequenceService.getNextSeq("JJILLEGALACTIVITYINFOSEQ"));
                    punishMapper.insertStatePunish(punishInfoVO);
                }
            } catch (Exception e) {
                logger.info("失败：" + e.toString());
            }
        } else if (billstate > 1) {
            punishMapper.updatePunishInfoState(sn, data);
        }
    }


    /**
     * @param punishVO 交管罚没对象
     * @auther dinggaofei
     * @Date 2022/12/21 16:23
     * @description 滞纳金
     */
    public BaseResult getLatefee(PunishInfoVO punishVO) {

        punishVO = punishMapper.findPunishLatefee(punishVO.getPunishbillnum());
        //xml解析器
        Serializer serializer = new Persister();
        //xml转换器
        StringWriter sw = new StringWriter();
        try {
            BaseResult ret = new BaseResult();
            //已缴费的直接返回
            if (punishVO != null && punishVO.getBillstate() == 3) {
                PunishLatefee latefee = new PunishLatefee();
                latefee.setPunishbillnum(punishVO.getPunishbillnum());
                latefee.setBillstate("3");
                serializer.write(latefee, sw);
                ret.setData(sw.toString());
                return ret;
            }
            //更新messageid
            long messageid = sequenceService.getNextSeq("ELEMESSAGESEQ");
            if (punishVO == null) {
                long punishinfoid = sequenceService.getNextSeq("JJILLEGALACTIVITYINFOSEQ");
                punishVO = new PunishInfoVO();
                punishVO.setPunishinfoid(punishinfoid);
                punishVO.setPunishbillnum(punishVO.getPunishbillnum());
                punishVO.setMessageid(messageid);
                punishMapper.insertBlankPunish(punishVO);
            } else {
                punishVO.setMessageid(messageid);
                punishMapper.updateMsgPunish(punishVO);
            }

            //从财政查询
            boolean suc = messageService.sendAndRecvMessage("GETLATEFEE", messageid, MessageFactory.getLatefee(punishVO), null);
            if (suc) {
                punishVO = punishMapper.findPunishLatefee(punishVO.getPunishbillnum());
                PunishLatefee latefee = punishVO.getLatefees();
                serializer.write(latefee, sw);
                ret.setData(sw.toString());
                return ret;
            }
            return null;
        } catch (Exception e) {
            logger.info("失败：" + e.toString());
            return new BaseResult(ErrorCodeEnum.TLQ_ERR);
        }
    }

    public BaseResult setPunishInfo(String message) {
        //xml解析器
        Serializer serializer = new Persister();
        try {
            long messageid = sequenceService.getNextSeq("ELEMESSAGESEQ");

            SetPunishinfo punishinfo = serializer.read(SetPunishinfo.class, new StringReader(message));
            PunishInfoVO punishVO = new PunishInfoVO(punishinfo);
            ArrayList<SetPunishinfoDetail> detail = punishinfo.getDetail();
            int id = punishMapper.findPunishMax(punishVO);
            for (SetPunishinfoDetail setDdetail : detail
            ) {
                PunishDetailInfoVO punishDetailInfoVO = new PunishDetailInfoVO(setDdetail);
                punishVO.setMessageid(messageid);
                if (id > 0) {
                    punishMapper.deletePunishdetail(punishDetailInfoVO.getPunishinfoid());
                }
                punishMapper.insertPunishDetailInfo(punishDetailInfoVO);
            }
            int billid = 0;
            if (id > 0) {
                billid = punishMapper.updatePunishInfo(punishVO);
            } else {
                punishVO.setSendtime(sdf.format(new Date()));
                billid = punishMapper.insertPunishInfo(punishVO);
            }
            if (billid < 0) {
                return new BaseResult(ErrorCodeEnum.DB_ERR);
            }
            //发送财政
            Object obj = MessageFactory.setPunishInfo(punishVO);
            messageService.sendMessage("SETPUNISHINFO", messageid, obj, "2.0");
        } catch (
                Exception e) {
            logger.info("失败：" + e.toString());
        }
        return new BaseResult();

    }

    public void updateIllegalactivitySendState(String sn, int info) {
        try {
            illegalactivityinfoMapper.updateActiviInfoIssend(sn, info);
        } catch (Exception e) {
            logger.info(e.toString());
        }
    }
//页面

    /**
     * 通用罚没列表
     *
     * @param punishInfoVO
     * @param pagination
     * @return
     */
    public List<PunishInfoVO> findPunishPage(PunishInfoVO punishInfoVO, Pagination pagination) {
        if (pagination.getRows() > 0) PageHelper.startPage(pagination.getPage(), pagination.getRows());
        return  punishMapper.findPunishPage(punishInfoVO);
    }

    public BaseResult getPunish(Long punishinfoid) {
        return new BaseResult(punishMapper.getPunish(punishinfoid));
    }

    /**
     * 发送通用罚没单据
     *
     * @param billids
     * @param userpwd
     * @param usercode
     * @return
     */
    public BaseResult sendPunish(List<String> billids, String userpwd, String usercode) {
        //2024更正
        userpwd = (new MD5().md5s(userpwd));
        if (userMapper.getUserCount(userpwd, usercode) > 0) {
            try {
                if (billids != null && billids.size() > 0) {
                    List<PunishInfoVO> punishPage = punishMapper.findPunishByid(billids);
                    if ((punishPage.size() > 0)) {
                        for (PunishInfoVO vos : punishPage) {

                            long messageid = sequenceService.getNextSeq("ELEMESSAGESEQ");
                            Object obj = MessageFactory.setPunishInfo(vos);
                            messageService.sendMessage("SETPUNISHINFOPZK", messageid, obj, "2.0");
// 写凭证
                            if (nonTaxConfig.IS_Pzk) {
                                PzkService.sendPzk("SETETICKETNUMDEPOSITPZK", obj);
                            }
                            return new BaseResult(vos);
                        }
                    } else {
                        return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "单据不存在");
                    }
                }
            }catch (Exception e){

            }

        } else {
            return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "用户信息验证失败");
        }
        return new BaseResult(ErrorCodeEnum.UNKNOWN_ERR);
    }


    /**
     * 冲销通用罚没单据
     *
     * @param billids
     * @param userpwd
     * @param usercode
     * @return
     */
    public BaseResult cleanPunish(List<String>billids, String userpwd, String usercode) {

        try {
            String errinfo = "";
            //2024更正
            userpwd = (new MD5().md5s(userpwd));
            if (userMapper.getUserCount(userpwd, usercode) > 0) {
                if (billids != null && billids.size() >0) {
                    List<PunishInfoVO> punishPage = punishMapper.findPunishByid(billids);
                    for (PunishInfoVO vos : punishPage
                    ) {
                        if (vos.getSendtime().equals("")) {
                            setPunishInfoBackOut(vos);
                            punishMapper.updateIsbankaffirm(vos.getPunishinfoid());   // 和旧项目有区别,没有这个isbankaffirm 字段
                        } else {
                            Date date = new Date();
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                            Date date2 = sdf.parse(vos.getSendtime());
                            long temp = date.getTime() - date2.getTime();    //相差毫秒数
                            long hours = temp / 1000 / 3600;                //相差小时数
                            long temp2 = temp % (1000 * 3600);
                            long mins = temp2 / 1000 / 60;                    //相差分钟数
                            if (((hours * 60) + mins) < (nonTaxConfig.CxTime)) {
                                setPunishInfoBackOut(vos);
                                punishMapper.updateIsbankaffirm(vos.getPunishinfoid());   // 和旧项目有区别,没有这个isbankaffirm 字段
                            } else {
                                errinfo += vos.getPunishbillnum();
                            }
                        }

                    }
                    if (!errinfo.equals("")) {
                        errinfo = errinfo.substring(0, errinfo.length() - 1) + "超时冲销失败,其他单据冲销成功!";
                        return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), errinfo);
                    } else {
                        errinfo = "冲销成功";
                        return new BaseResult(ErrorCodeEnum.SUCCESS.getCode(), errinfo);
                    }

                } else {
                    return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "单号不存在");
                }
            } else {
                return new BaseResult(ErrorCodeEnum.CUSTOM_ERR.getCode(), "用户信息验证失败");
            }
        } catch (Exception e) {
            return new BaseResult(ErrorCodeEnum.UNKNOWN_ERR);
        }

    }

    private BaseResult setPunishInfoBackOut(PunishInfoVO vos) {

        //xml解析器
        Serializer serializer = new Persister();
        //xml转换器
        StringWriter sw = new StringWriter();
        try {
            Long messageid = sequenceService.getNextSeq("ELEMESSAGESEQ");
            SetDeductBackOut setPunishinfoOut = (SetDeductBackOut) MessageFactory.getSetPunishinfoOut(vos);
            setPunishinfoOut.setRemark("");
            setPunishinfoOut.setBackoutname("");
            serializer.write(setPunishinfoOut, sw);
            messageService.sendMessage("", messageid, setPunishinfoOut, "SETPUNISHINFOBACKOUT");
            if (nonTaxConfig.IS_Pzk) {
                PzkService.sendPzk("SETPUNISHINFOBACKOUTPZK", setPunishinfoOut);
            }
        } catch (Exception e) {
            logger.info("失败：" + e.toString());
            return new BaseResult(ErrorCodeEnum.TLQ_ERR);
        }
        return new BaseResult();
    }

    /**
     * 导出通用罚没单据
     * @param billids id集合
     * @param accountcode 收款账户
     * @param response
     */
    public void punishExport(List<String>billids,String accountcode, HttpServletResponse response) {

        List<PunishInfoVO> punishPage = punishMapper.findPunish(billids,accountcode);
        String[] headers = {"流水号", "处罚决定书号", "区划编码", "区划名称", "单位id", "单位编码", "单位名称", "票据年度", "政策文件", "主体机关代码", "当事人/单位", "地址", "违法行为", "政策规定", "法律依据", "罚没决定", "罚没金额", "滞纳金", "处罚日期", "代录日期", "是否减免滞纳金", "收款银行id", "账户名", "账号", "银行名称", "发送时间", "__status", "是否发送"};
        String[] col = {"punishinfoid", "punishbillnum", "cantoncode", "cantonname", "unitid", "unitcode", "unitname", "billyear", "policyfiles", "suborg", "penaltyobjects", "address", "illegal", "regulations", "punishbasis", "punishdecision", "punishamt", "latefee", "punishdate", "recorddate", "isremission", "bankid", "accountname", "accountcode", "bankname", "sendtime", "", "issend"};
        ExportSXSSFUtil ex = new ExportSXSSFUtil();
        SXSSFWorkbook workbook = ex.exportExcelSXSSF("通用罚没列表", headers, col, punishPage, null);
        response.setContentType("application/vnd.ms-excel");
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" +
                    new String(("通用罚没列表.xls").getBytes(), "iso-8859-1"));
            OutputStream ouputStream = response.getOutputStream();
            workbook.write(ouputStream);
            ouputStream.flush();
            ouputStream.close();
        } catch (Exception e) {
            logger.info("导出失败：" + e.toString());
        }
    }

    @Resource
    private ChargeBillMapper chargeBillMapper;
    @Resource
    private BankMapper bankMapper;
    @Resource
    private PayWayMapper payWayMapper;
    @Resource
    private OnlineOrderMapper onlineOrderMapper;

    public BaseResult setPayInfo(String billnum,String accountcode,int isnohere,int isspecialbill,String specialbillnum,String paybankdt,String bankaffirm,String bankstation,String paywaycode,String paychnl,String payeraccount){
        if(paywaycode.length()==1){
            paywaycode="0"+paywaycode;
        }
        //限制条件
        String errnum="";
        if(billnum==null||"".equals(billnum)){
            errnum="errnum=1";
        }
        else if(paybankdt==null||"".equals(paybankdt)){
            errnum="errnum=2";
        }
        else if(bankaffirm==null||"".equals(bankaffirm)){
            errnum="errnum=3";
        }
        else if(bankstation==null||"".equals(bankstation)){
            errnum="errnum=4";
        }
        else if(Integer.toString(chargeBillMapper.findPayWay(paywaycode))==null||"0".equals(Integer.toString(chargeBillMapper.findPayWay(paywaycode)))
                ||"".equals(Integer.toString(chargeBillMapper.findPayWay(paywaycode)))){
            errnum="errnum=5";
        }
        if(!"".equals(errnum)){
            System.out.println("失败，错误代码"+errnum);
            return new BaseResult("01","失败，错误代码"+errnum);
        }
        try {

            long messageid = sequenceService.getNextSeq("ELEMESSAGESEQ");
//            //修改付款时更新messageid
            Long bankId = bankMapper.findBankId(accountcode);
            int payWayMaxPaywayid = payWayMapper.findPayWayMaxPaywayid(paywaycode);
            punishMapper.updateIllegalactivityBankAffirm(billnum, bankId, isnohere, isspecialbill, specialbillnum, paybankdt, bankaffirm, bankstation, payWayMaxPaywayid, String.valueOf(messageid),sdf.format(new Date()));
            SetPayinfo payinfo = punishMapper.getActiviInfo(billnum);

            BigDecimal funds= new BigDecimal(payinfo.getFunds());
            BigDecimal latefee = new BigDecimal(payinfo.getLatefee());

            OnlineOrder oo = new OnlineOrder();
            oo.setBillnum(billnum);
            oo.setAmt(funds.add(latefee).toPlainString());
            oo.setBankaffirm(bankaffirm);
            oo.setBilltype(3);
            oo.setPaybankdt(paybankdt);
            oo.setPaychnl(paychnl);
            Bank bank = bankMapper.findBankByBankidIsenable(Long.valueOf(payinfo.getBankid()));
            oo.setPayee(bank.getAccountname());
            oo.setPayeeaccount(bank.getAccountcode());
            oo.setPayer(payinfo.getOccurname());
            oo.setPayeraccount(payeraccount);
            onlineOrderMapper.saveOnlineOrder(oo);
            messageService.sendMessage("SETPAYINFO", messageid, payinfo, "2.0");
            // 写凭证
            if (nonTaxConfig.IS_Pzk) {
                PzkService.sendPzk("SETPAYINFOPZK", payinfo);
            }
            return new BaseResult();
        } catch (Exception e) {
            logger.info("失败："+e.toString());
            return new BaseResult("01","发送失败");
        }finally{
        }
    }
}
